﻿using System;
using System.Collections.Generic;
using System.Text;
using System.Drawing;
using System.Windows.Forms;
using SFP;
using SFP.Animation2D;
using SFP.Audio;
using SFP.Input;

namespace TestGame
{
    public class MyGame : Game
    {
        public const double GRAVITY = 1000;
        public static readonly Size RESOLUTION = new Size(640, 480);

        Form form;

        LayerManager layerManager;
        LayerManager.Bitmaps bitmaps;

        Player player;
        
        double clockTime = 0;
        int clockSec;
        int clockMin;
        int clockHrs;

        public MyGame(Size resolution) : base(resolution)
        {
            showFPS = true;
            limitFrameRate = false;
            maxFrameRate = 60;
            
            form = GetForm();
            form.StartPosition = FormStartPosition.CenterScreen;
            
        }

        public LayerManager GetLayerManager()
        {
            return layerManager;
        }

        protected override void Initialize()
        {
            layerManager = new LayerManager();
            player = new Player(100, resolution.Height - 150, this);
            CollisionReactions.BlockReaction = new Block(player, layerManager);
            CollisionReactions.ItemBlockReaction = new ItemBlock(player, layerManager);
            CollisionReactions.CoinReaction = new Coin(player, layerManager);
            CollisionReactions.ObstaclekReaction = new Obstacle(player, layerManager);
        }

        protected override void LoadContent()
        {
            layerManager.load(ContentLoader.LoadXML("Level\\desert.xml"), resolution, out bitmaps, true);
            CollisionReactions.BlockReaction.loadBlockParticleSystem();
            GameObjects.Blocks = GameObject.GetHashSetByType(layerManager.getLayer(2), "Block");
            GameObjects.ItemBlocks = GameObject.GetHashSetByType(layerManager.getLayer(2), "ItemBlock");
            GameObjects.Coins = GameObject.GetHashSetByType(layerManager.getLayer(2), "Coin");

            player.loadBitmaps();
            Ressources.EMPTY_ITEM_BLOCK = ContentLoader.LoadBitmap("images\\block_emp.png");

            // Load audio
            Ressources.MAIN_THEME = ContentLoader.LoadAudio("Content\\sm1theme.mid");
            Ressources.JUMP_SOUND = ContentLoader.LoadAudio("Content\\smb_jumpsmall.wav");
            Ressources.COIN_SOUND = ContentLoader.LoadAudio("Content\\smb_coin.wav");
            Ressources.BREAK_BLOCK = ContentLoader.LoadAudio("Content\\smb_breakblock.wav");
            AudioPlayer.loop(Ressources.MAIN_THEME);
        }

        protected override void UnloadContent()
        {
        }

        private Nullable<Point> lastMouseLocation;

        protected override void Update(double time)
        {
            KeyboardState keyStates = Keyboard.GetKeyboardState();
            if (time > 50) time = 50;

            updateAudio(keyStates);
            updateLayerManager(time, keyStates);
            player.update(time, keyStates);
            CollisionReactions.BlockReaction.updateBlockParticleSystem(time);
            updateClockTime(time);
            updateForm(keyStates);
        }

        private void updateAudio(KeyboardState keyStates)
        {
            if (keyStates.isKeyDownNotPressed(Keys.P)) // Start Loop
            {
                AudioPlayer.loop(Ressources.MAIN_THEME);
            }
            else if (keyStates.isKeyDownNotPressed(Keys.S)) // Stop
            {
                AudioPlayer.stop(Ressources.MAIN_THEME);
            }
            else if (keyStates.isKeyDownNotPressed(Keys.H)) // Pause
            {
                AudioPlayer.pause(Ressources.MAIN_THEME);
            }
        }

        private void updateLayerManager(double time, KeyboardState keyStates)
        {
            /* Change bitmaps... */
            if (keyStates.isKeyDownNotPressed(Keys.C))
            {
                Bitmap a = bitmaps.GetBitmapByID(1);
                a.RotateFlip(RotateFlipType.RotateNoneFlipX);
            }

            /* Process mouse input... */

            if (Mouse.isLButtonClicked())
            {
                Point mLoc = Mouse.getCurrentLocation();

                if (lastMouseLocation != null)
                {
                    layerManager.scrollX(((Point)lastMouseLocation).X - mLoc.X);
                    layerManager.scrollY(mLoc.Y - ((Point)lastMouseLocation).Y);
                }

                lastMouseLocation = mLoc;
            }
            else
            {
                lastMouseLocation = null;
            }

            /* Process keyboard input... */

            bool turboMove = false;
            if (keyStates.isKeyDown(Keys.ShiftKey))
            {
                turboMove = true;
            }

            double scrollValue = .4;
            if (turboMove) scrollValue *= 4;

            if (keyStates.isKeyDown(Keys.Left))
            {
                layerManager.scrollX(-scrollValue * time);
            }
            else if (keyStates.isKeyDown(Keys.Right))
            {
                layerManager.scrollX(scrollValue * time);
            }
            if (keyStates.isKeyDown(Keys.Up))
            {
                layerManager.scrollY(scrollValue * time * 2);
            }
            else if (keyStates.isKeyDown(Keys.Down))
            {
                layerManager.scrollY(-scrollValue * time);
            }
        }

        private void updateClockTime(double time)
        {
            clockTime += time;
            clockSec = (int)((clockTime / 1000) % 60);
            clockMin = (int)(((clockTime / 1000) / 60) % 60);
            clockHrs = (int)((((clockTime / 1000) / 60) / 60) % 24);
        }

        public void updateForm(KeyboardState keyStates)
        {
            if (keyStates.isKeyDownNotPressed(Keys.M))
            {
                Form form = GetForm();
                if (form.WindowState != FormWindowState.Maximized)
                {
                    form.WindowState = FormWindowState.Maximized;
                }
                else
                {
                    form.WindowState = FormWindowState.Normal;
                }
            }

            if (keyStates.isKeyDownNotPressed(Keys.F))
                limitFrameRate = !limitFrameRate;

            if (keyStates.isKeyDown(Keys.Escape))
                Exit();
        }
        
        protected override void Draw(Graphics graphics)
        {
            /* Draw layer objects... */
            layerManager.draw(graphics);

            /* Draw player... */
            player.draw(graphics);

            /* Draw clock time... */
            DateTime currentTime = new DateTime(1, 1, 1, clockHrs, clockMin, clockSec);
            graphics.FillRectangle(new SolidBrush(Color.Black), resolution.Width - 95, 5, 92, 22);
            graphics.DrawString(currentTime.ToLongTimeString(), new Font("Arial", 16), new SolidBrush(Color.Yellow), new PointF(resolution.Width - 95, 5));
        }
    }
}
